using Microsoft.Phone.Controls;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Media;
namespace Microsoft.Phone.Gestures
{
	internal abstract class GestureHelper
	{
		private enum DragLock
		{
			Unset,
			Free,
			Vertical,
			Horizontal
		}
		private GestureHelper.DragLock _dragLock;
		private bool _dragging;
		private WeakReference _gestureSource;
		private Point _gestureOrigin;
		private readonly Size DeadZoneInPixels = new Size(12.0, 12.0);
		public event EventHandler<GestureEventArgs> GestureStart
		{
			[MethodImpl(32)]
			add
			{
				this.GestureStart = (EventHandler<GestureEventArgs>)Delegate.Combine(this.GestureStart, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.GestureStart = (EventHandler<GestureEventArgs>)Delegate.Remove(this.GestureStart, value);
			}
		}
		public event EventHandler<FlickEventArgs> Flick
		{
			[MethodImpl(32)]
			add
			{
				this.Flick = (EventHandler<FlickEventArgs>)Delegate.Combine(this.Flick, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.Flick = (EventHandler<FlickEventArgs>)Delegate.Remove(this.Flick, value);
			}
		}
		public event EventHandler<EventArgs> GestureEnd
		{
			[MethodImpl(32)]
			add
			{
				this.GestureEnd = (EventHandler<EventArgs>)Delegate.Combine(this.GestureEnd, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.GestureEnd = (EventHandler<EventArgs>)Delegate.Remove(this.GestureEnd, value);
			}
		}
		public event EventHandler<DragEventArgs> HorizontalDrag
		{
			[MethodImpl(32)]
			add
			{
				this.HorizontalDrag = (EventHandler<DragEventArgs>)Delegate.Combine(this.HorizontalDrag, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.HorizontalDrag = (EventHandler<DragEventArgs>)Delegate.Remove(this.HorizontalDrag, value);
			}
		}
		public event EventHandler<DragEventArgs> VerticalDrag
		{
			[MethodImpl(32)]
			add
			{
				this.VerticalDrag = (EventHandler<DragEventArgs>)Delegate.Combine(this.VerticalDrag, value);
			}
			[MethodImpl(32)]
			remove
			{
				this.VerticalDrag = (EventHandler<DragEventArgs>)Delegate.Remove(this.VerticalDrag, value);
			}
		}
		protected bool ShouldHandleAllDrags
		{
			get;
			private set;
		}
		protected UIElement Target
		{
			get;
			private set;
		}
		public static GestureHelper Create(UIElement target)
		{
			return GestureHelper.Create(target, true);
		}
		public static GestureHelper Create(UIElement target, bool shouldHandleAllDrags)
		{
			GestureHelper gestureHelper = new ManipulationGestureHelper(target, shouldHandleAllDrags);
			gestureHelper.Start();
			return gestureHelper;
		}
		protected GestureHelper(UIElement target, bool shouldHandleAllDrags)
		{
			this.Target = target;
			this.ShouldHandleAllDrags = shouldHandleAllDrags;
		}
		protected abstract void HookEvents();
		public void Start()
		{
			this.HookEvents();
		}
		protected void NotifyDown(InputBaseArgs args)
		{
			GestureEventArgs args2 = new GestureEventArgs();
			this._gestureSource = new WeakReference(args.Source);
			this._gestureOrigin = args.Origin;
			this._dragLock = GestureHelper.DragLock.Unset;
			this._dragging = false;
			this.RaiseGestureStart(args2);
		}
		protected void NotifyMove(InputDeltaArgs args)
		{
			if (Math.Abs(args.CumulativeTranslation.get_X()) > this.DeadZoneInPixels.get_Width() || Math.Abs(args.CumulativeTranslation.get_Y()) > this.DeadZoneInPixels.get_Height())
			{
				if (!this._dragging)
				{
					this.ReleaseMouseCaptureAtGestureOrigin();
				}
				this._dragging = true;
				if (this._dragLock == GestureHelper.DragLock.Unset)
				{
					double num = GestureHelper.AngleFromVector(args.CumulativeTranslation.get_X(), args.CumulativeTranslation.get_Y()) % 180.0;
					if (num > 45.0 && num < 135.0)
					{
						if (num > 45.0 && num < 135.0)
						{
							this._dragLock = GestureHelper.DragLock.Vertical;
						}
						else
						{
							this._dragLock = GestureHelper.DragLock.Free;
						}
					}
					else
					{
						this._dragLock = GestureHelper.DragLock.Horizontal;
					}
				}
			}
			if (!this._dragging)
			{
				return;
			}
			this.RaiseDragEvents(args);
		}
		private void ReleaseMouseCaptureAtGestureOrigin()
		{
			if (this._gestureSource == null)
			{
				return;
			}
			FrameworkElement frameworkElement = this._gestureSource.get_Target() as FrameworkElement;
			if (frameworkElement == null)
			{
				return;
			}
			GeneralTransform generalTransform = frameworkElement.TransformToVisual(null);
			Point point = generalTransform.Transform(this._gestureOrigin);
			using (IEnumerator<UIElement> enumerator = VisualTreeHelper.FindElementsInHostCoordinates(point, Application.get_Current().get_RootVisual()).GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					UIElement current = enumerator.get_Current();
					current.ReleaseMouseCapture();
				}
			}
		}
		protected void NotifyUp(InputCompletedArgs args)
		{
			EventArgs args2 = EventArgs.Empty;
			this._dragLock = GestureHelper.DragLock.Unset;
			this._dragging = false;
			if (args.IsInertial)
			{
				double num = GestureHelper.AngleFromVector(args.FinalLinearVelocity.get_X(), args.FinalLinearVelocity.get_Y());
				if (num > 45.0 && num < 315.0)
				{
					if (num >= 135.0 && num <= 225.0)
					{
						num = 180.0;
					}
				}
				else
				{
					num = 0.0;
				}
				FlickEventArgs args3 = new FlickEventArgs
				{
					Angle = num
				};
				this.ReleaseMouseCaptureAtGestureOrigin();
				this.RaiseFlick(args3);
			}
			else
			{
				if (args.TotalTranslation.get_X() != 0.0 || args.TotalTranslation.get_Y() != 0.0)
				{
					DragEventArgs dragEventArgs = new DragEventArgs
					{
						CumulativeDistance = args.TotalTranslation
					};
					dragEventArgs.MarkAsFinalTouchManipulation();
					args2 = dragEventArgs;
				}
			}
			this.RaiseGestureEnd(args2);
		}
		private void RaiseGestureStart(GestureEventArgs args)
		{
			SafeRaise.Raise<GestureEventArgs>(this.GestureStart, this, args);
		}
		private void RaiseFlick(FlickEventArgs args)
		{
			SafeRaise.Raise<FlickEventArgs>(this.Flick, this, args);
		}
		private void RaiseGestureEnd(EventArgs args)
		{
			SafeRaise.Raise<EventArgs>(this.GestureEnd, this, args);
		}
		private void RaiseDragEvents(InputDeltaArgs args)
		{
			DragEventArgs args2 = new DragEventArgs(args);
			if (args.DeltaTranslation.get_X() != 0.0 && this._dragLock == GestureHelper.DragLock.Horizontal)
			{
				this.RaiseHorizontalDrag(args2);
				return;
			}
			if (args.DeltaTranslation.get_Y() != 0.0 && this._dragLock == GestureHelper.DragLock.Vertical)
			{
				this.RaiseVerticalDrag(args2);
			}
		}
		private void RaiseHorizontalDrag(DragEventArgs args)
		{
			SafeRaise.Raise<DragEventArgs>(this.HorizontalDrag, this, args);
		}
		private void RaiseVerticalDrag(DragEventArgs args)
		{
			SafeRaise.Raise<DragEventArgs>(this.VerticalDrag, this, args);
		}
		private static double AngleFromVector(double x, double y)
		{
			double num = Math.Atan2(y, x);
			if (num < 0.0)
			{
				num = 6.2831853071795862 + num;
			}
			return num * 360.0 / 6.2831853071795862;
		}
	}
}
